函式在即使非 JavaScript 的程式語言中是非常重要的一塊,我們會根據需求在函式中建立一系列動作,需要的時候便接呼叫對應函式,不管需求是執行 Ajax API ,或是隱藏、顯示畫面中某某區塊,都會將這些需求寫在函式中。
呼叫函式的方法,使用函式名稱搭配小刮號 ()
function Fn1(){
console.log('一般函式')
}
Fn1()
也可以在小刮號中寫入參數,參數會帶到函式中,而函式的參數只跟在函式中建立的變數一樣,他的作用域只存在於函式中。
function Fn1(num){
console.log(num) //1
}
Fn1(1)
console.log(num) //num
實做中常常看到在函式 return
某個值,而其實 return
的值會直接回傳在呼叫函式的方法中,這種方法常用在會要執行某些重複動作的需求上。
function Fn1(num){
var sum = num + 10
return sum
}
console.log(Fn1(1) , Fn1(2)) //11, 12
上面有介紹到函式帶參數功能,關於參數也有一個特別的功能,就是 arguments
。
arguments
這個語法在函式建立時,他也會被一同建立,即使我們不需告變數、參數他也會存在於函式中,而 arguments
其實就是我們呼叫函式時,所有參數組和而成的 類陣列。
function Fn1(){
console.log(arguments) //Arguments(3) [1, 2, 3, .... ]
}
Fn1(1,2,3)
什麼是類陣列呢?簡單來講就是一個類似陣列但不是陣列的東西,但是類陣列與陣列最大差異在於可以使用的方法 or 功能會有很大差異,因此我們來看一下範例:
var a = ['1', '2', '3'];
console.dir(a);
點開變數 a
中的 [[Prototype]]
底下都會是陣列中的方法(太長因此不全部截圖):
而 arguments
中的 [[Prototype]]
就只有:
可以看的出來類陣列和原始陣列中的方法相差十分多。
當我們參數名稱和函式外層變數相同時,看看花生神魔術
var name ='Ryder'
function Fn1(name){
console.log(name) // Jack
}
Fn1('Jack')
結果會是以傳入參數為準。
那麼看看對參數使用 =
運算子賦予一個新的值看看結果如何:
function Fn1(name){
name = 'Annie'
console.log(name) // Annie
}
Fn1('Jack')
結果會發現參數的值確實可以更改,其實參數跟函式中變數的範圍練特性是差不多的,當內層有該參數時,就會優先指向內層參數。
在 ES6 語法中有新增一個預設參數方法,只需在參數旁邊使用 =
運算子賦值,之後呼叫函式時,若沒帶上參數,到了函式中參數便會套上預設的值,但如果呼叫函式時,有帶上參數,便還是以帶上的參數為主,是一個十分方變的功能:
function Fn1(name = 'Annie'){
return name
}
console.log(Fn1()) //Annie
console.log(Fn1('Jack')) //Jack
先前也有介紹到物件傳參考這個特性,當我們物件傳入參數時,他也會是傳參考, :
var obj1 = { name:'Ryder' }
function Fn1(item){
item.name = 'Annie'
console.log(item.name, obj1.name) // Annie , Annie
}
Fn1(obj1 )
範例中兩個物件的 name
屬性的值也都會改成 'Annie'
。
不過當我們只是傳入物件中的屬性時,結果並非是傳參考,而僅僅是傳值
var obj1 = { name:'Ryder' }
function Fn1(item){
item = 'Annie'
console.log(item, obj1.name) // Annie , Ryder
}
Fn1(obj1.name)
因此有使用 ES Lint 時,如果有試者修改參數的值,他都會跳出請不要直接修改參數的相關警告,這點就是避免物件傳參考特性發生錯誤。
最後來說說函式的分類,在先前 陳述式 /表達式 中有根據建立方法不同,將函式分成:
但這其實是根據這段語法是表達式、陳述式來做區分,或者說函式有沒有名字來做分類的,在 ES6 新增箭頭函式後,一般會把函式分成三種:
function Fn1(){
console.log('傳統具名')
}
Fn1()
var Fn2 = function(){
console.log('傳統匿名')
}
Fn2()
(function(){
console.log('立即函式')
})()
var Fn3 = ()=> {
console.log('箭頭函式')
}
Fn3()